package com.youlu.campus.service.order;

import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.ActivityInfo;
import com.youlu.campus.entity.MerchantSharingProfitInfo;
import com.youlu.campus.entity.OrderInfo;
import com.youlu.campus.entity.enums.SharingProfitOrderTypeEnum;
import com.youlu.campus.entity.enums.SharingProfitStatus;
import com.youlu.campus.entity.order.SharingProfitOrderDetail;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class MerchantSharingProfitService {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 分账比例不能为0
     */
    private final Double ZERO = 0d;
    /**
     * 分账比例不能超过60%
     */
    private final Double MAX_RATIO = 60d;

    public static void main(String[] args) {
        LocalDateTime localDateTime = LocalDateTime.now().plusHours(12L);
        System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }


    /**
     * 退款处理清除分账记录
     *
     * @param orderNo 订单号
     */
    @Async
    public void doRefund(String orderNo) {
        log.info("【分账退款】orderNo:{}", orderNo);
        if (StringUtils.isBlank(orderNo)) {
            return;
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo));
        query.addCriteria(Criteria.where("sharingProfitStatus").is(SharingProfitStatus.UNHANDLED.getValue()));
        boolean exists = this.mongoTemplate.exists(query, SharingProfitOrderDetail.class);
        if (!exists) {
            log.error("【分账退款】orderNo:{} 未找到订单分账记录", orderNo);
            return;
        }
        Update update = new Update();
        update.set("sharingProfitStatus", SharingProfitStatus.CANCEL.getValue());
        update.set("remark", "订单退款取消分账");
        update.set("updatedTime", new Date());
        UpdateResult updateResult = this.mongoTemplate.updateMulti(query, update, SharingProfitOrderDetail.class);
        log.info("【分账退款】orderNo:{} 更新分账记录取消分账:{}", orderNo, updateResult.getModifiedCount());
//        LocalDateTime current = LocalDateTime.now();
//        LocalDateTime payTimeAfter = LocalDateTime.ofInstant(payTime.toInstant(), ZoneId.systemDefault()).plusHours
//        (12L);
//        log.info("【分账退款】orderNo:{} | payTime:{} currentTime:{}| payTimeAfter:{} ", orderNo, payTime,current);
//        if(current.isBefore(payTimeAfter)){
//
//        }


    }

    public SharingProfitOrderDetail getSharingProfitAmountByOrderNo(String orderNo) {
        Query query = new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo));
        //query.addCriteria(Criteria.where("sharingProfitStatus").is(SharingProfitStatus.UNHANDLED.getValue()));
        SharingProfitOrderDetail sharingProfitOrderDetail = this.mongoTemplate.findOne(query,
                SharingProfitOrderDetail.class);
        if (Objects.nonNull(sharingProfitOrderDetail)) {
            return sharingProfitOrderDetail;
        }
        return null;
    }

    public List<SharingProfitOrderDetail> getSharingProfitListByOrderNo(String orderNo) {
        Query query = new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo));
        List<SharingProfitOrderDetail> list = this.mongoTemplate.find(query,SharingProfitOrderDetail.class);
        return list;
    }

    public MerchantSharingProfitInfo getSharingProfitConfigByActivityId(String activityId) {
        ActivityInfo activityInfo = this.mongoTemplate.findById(activityId, ActivityInfo.class);
        if (Objects.isNull(activityInfo)) {
            new BusinessException("活动不存在");
        }
        MerchantSharingProfitInfo merchantSharingProfit = activityInfo.getMerchantSharingProfit();
        if (Objects.isNull(merchantSharingProfit)) {
            return new MerchantSharingProfitInfo();
        }
        List<MerchantSharingProfitInfo> list = merchantSharingProfit.getMerchantSharingProfits();
        if(CollectionUtils.isEmpty(list)){
            list = new ArrayList<>();
            MerchantSharingProfitInfo info = new MerchantSharingProfitInfo();
            info.setSharingProfitType(merchantSharingProfit.getSharingProfitType());
            info.setSharingProfitAccount(merchantSharingProfit.getSharingProfitAccount());
            info.setSharingProfit(merchantSharingProfit.getSharingProfit());
            info.setDigitalCaSharingProfitRatio(merchantSharingProfit.getDigitalCaSharingProfitRatio());
            info.setPaperCaSharingProfitRatio(merchantSharingProfit.getPaperCaSharingProfitRatio());
            info.setVideoOrderSharingProfitRatio(merchantSharingProfit.getVideoOrderSharingProfitRatio());
            info.setChuSaiSharingProfitRatio(merchantSharingProfit.getChuSaiSharingProfitRatio());
            info.setFuSaiSharingProfitRatio(merchantSharingProfit.getFuSaiSharingProfitRatio());
            info.setJueSaiSharingProfitRatio(merchantSharingProfit.getJueSaiSharingProfitRatio());
            list.add(info);
            merchantSharingProfit.setMerchantSharingProfits(list);
        }
        return merchantSharingProfit;
    }

    public void saveSharingProfitConfig(String activityId, MerchantSharingProfitInfo merchantSharingProfitInfo) {
        if (Objects.isNull(merchantSharingProfitInfo)) {
            return;
        }
        Boolean exist = merchantSharingProfitInfo.checkMaxSharingProfitRatio(MAX_RATIO);
        if (exist) {
            throw new BusinessException("分账比例不能超过60%");
        }
        ActivityInfo activityInfo = this.mongoTemplate.findById(activityId, ActivityInfo.class);
        if (Objects.isNull(activityInfo)) {
            return;
        }
        if(CollectionUtils.isNotEmpty(merchantSharingProfitInfo.getMerchantSharingProfits())){
            int num = merchantSharingProfitInfo.getMerchantSharingProfits().size();
            int newSize = merchantSharingProfitInfo.getMerchantSharingProfits().stream().map(MerchantSharingProfitInfo::getSharingProfitAccount)
                    .collect(Collectors.toSet()).size();
            if(newSize < num){
                throw new BusinessException("多个账户Id中存在相同账户Id");
            }
        }
        activityInfo.setMerchantSharingProfit(merchantSharingProfitInfo);
        this.mongoTemplate.save(activityInfo);
    }


    @Async
    public void doSharingProfit(OrderInfo sharingProfitOrder) {
        String orderNo = sharingProfitOrder.getOrderNo();
        String activityId = sharingProfitOrder.getActivityId();
        Integer totalFee = sharingProfitOrder.getTotalFee();
        log.info("【订单分账】MerchantSharingProfitService.doSharingProfit start handle order->{} amount ->{}", orderNo,
                totalFee);
        ActivityInfo activityInfo = this.mongoTemplate.findById(activityId, ActivityInfo.class);
        if (Objects.isNull(activityInfo)) {
            log.error("【订单分账】活动不存在 MerchantSharingProfitService.doSharingProfit  activityId->{}", activityId);
            return;
        }
        MerchantSharingProfitInfo merchantSharingProfit = activityInfo.getMerchantSharingProfit();
        if (Objects.isNull(merchantSharingProfit) || !merchantSharingProfit.getSharingProfit()) {
            log.error("【订单分账】当前订单活动不支持分账 MerchantSharingProfitService.doSharingProfit  activityId->{} order->{}",
                    activityId, orderNo);
            return;
        }
        List<MerchantSharingProfitInfo> list = merchantSharingProfit.getMerchantSharingProfits();
        if(CollectionUtils.isEmpty(list)){
            addOrUpdateSharingProfit(sharingProfitOrder,merchantSharingProfit,activityInfo.getName(),1);
            return;
        }
        int num = list.size();
        for (MerchantSharingProfitInfo info : list) {
            addOrUpdateSharingProfit(sharingProfitOrder,info,activityInfo.getName(),num);
        }
    }
    public void addOrUpdateSharingProfit(OrderInfo sharingProfitOrder,MerchantSharingProfitInfo merchantSharingProfit,String activityName,Integer num){
        String orderNo = sharingProfitOrder.getOrderNo();
        String activityId = sharingProfitOrder.getActivityId();
        Integer totalFee = sharingProfitOrder.getTotalFee();
        String category = sharingProfitOrder.getCategory();
        String transactionId = sharingProfitOrder.getTransactionId();
        Double sharingProfitRatio = getSharingProfitRatio(sharingProfitOrder, merchantSharingProfit);
        log.info("【订单分账】MerchantSharingProfitService.doSharingProfit start handle order->{}| category->{}| 分账比例 ",
                orderNo, category, sharingProfitRatio);
        if (sharingProfitRatio.compareTo(ZERO) == 0 || sharingProfitRatio.compareTo(MAX_RATIO) == 1) {
            log.error("【订单分账】订单分账比例 不能为0 或者超过60% MerchantSharingProfitService.doSharingProfit  order->{}| " +
                    "category->{}| " +
                    "分账比例 ", orderNo, category, sharingProfitRatio);
            return;
        }
        if (totalFee == ZERO.intValue()) {
            log.warn("【订单分账】MerchantSharingProfitService.doSharingProfit 当前订单金额不满足分账要求 0 order->{} amount ->{}",
                    orderNo,
                    totalFee);
            return;
        }
        BigDecimal totalAmount = new BigDecimal(totalFee);
        BigDecimal sharingProfitRatioNew = new BigDecimal(sharingProfitRatio);
        BigDecimal divideRatio = sharingProfitRatioNew.divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
        int sharingProfitAmount = totalAmount.multiply(divideRatio).intValue();
        log.info("【订单分账】MerchantSharingProfitService.doSharingProfit  order->{}| category->{}| ratio->{}|" +
                        " sharingProfitAmount ->{}",
                orderNo, category, sharingProfitRatio, sharingProfitAmount);
        if (sharingProfitAmount <= 0) {
            log.error("【订单分账】MerchantSharingProfitService.doSharingProfit 分账金额错误不能为0 order->{}| category->{}| " +
                            "ratio->{}|" +
                            " sharingProfitAmount ->{}",
                    orderNo, category, sharingProfitRatio, sharingProfitAmount);
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("orderNo").is(orderNo).and("sharingProfitAccount").is(merchantSharingProfit.getSharingProfitAccount()));
        boolean exists = this.mongoTemplate.exists(query, SharingProfitOrderDetail.class);
        if (exists) {
            return;
        }
        Update update = new Update();
        update.set("activityId", activityId);
        update.set("sharingProfitType", merchantSharingProfit.getSharingProfitType());
        update.set("activityName", activityName);
        update.set("sharingProfitOrderType", SharingProfitOrderTypeEnum.valueOf(category));
        update.set("sharingProfitRatio", sharingProfitRatio);
        update.set("orderAmount", totalFee);
        update.set("sharingProfitAmount", sharingProfitAmount);
        update.set("sharingProfitAccount", merchantSharingProfit.getSharingProfitAccount());
        update.set("sharingProfitStatus", SharingProfitStatus.UNHANDLED.getValue());
        update.set("appId", sharingProfitOrder.getAppId());
        update.set("merchantId", sharingProfitOrder.getMechantId());
        update.set("merchantName", sharingProfitOrder.getMechantName());
        update.set("sharingProfitTotalNum", num);
        Date now = new Date();
        update.setOnInsert("createdTime", now);
        update.set("updatedTime", now);
        update.set("transactionId", transactionId);
        update.set("payTime", sharingProfitOrder.getPayTime());
        FindAndModifyOptions findAndModifyOptions = new FindAndModifyOptions();
        findAndModifyOptions.returnNew(Boolean.TRUE);
        findAndModifyOptions.upsert(Boolean.TRUE);
        this.mongoTemplate.findAndModify(query, update, findAndModifyOptions, SharingProfitOrderDetail.class);
    }

    public Double getSharingProfitRatio(OrderInfo sharingProfitOrder, MerchantSharingProfitInfo merchantSharingProfit) {

        //订单分类，由调用方法决定是纸质、电子 还是视频订单
        String category = sharingProfitOrder.getCategory();
        log.info("【订单分账】MerchantSharingProfitService.doSharingProfit start handle order->{} category->{}",
                sharingProfitOrder.getOrderNo(), category);
        if (SharingProfitOrderTypeEnum.DIGITAL_CA_ORDER.name().equals(category)) {
            return merchantSharingProfit.getDigitalCaSharingProfitRatio();
        }
        if (SharingProfitOrderTypeEnum.PAPER_CA_ORDER.name().equals(category)) {
            return merchantSharingProfit.getPaperCaSharingProfitRatio();
        }
        if (SharingProfitOrderTypeEnum.VIDEO_ORDER.name().equals(category)) {
            return merchantSharingProfit.getVideoOrderSharingProfitRatio();
        }
        if (SharingProfitOrderTypeEnum.CHU_SAI_ORDER.name().equals(category)) {
            return merchantSharingProfit.getChuSaiSharingProfitRatio();
        }
        if (SharingProfitOrderTypeEnum.FU_SAI_ORDER.name().equals(category)) {
            return merchantSharingProfit.getFuSaiSharingProfitRatio();
        }
        if (SharingProfitOrderTypeEnum.JUE_SAI_ORDER.name().equals(category)) {
            return merchantSharingProfit.getJueSaiSharingProfitRatio();
        }
        return ZERO;
    }


}
